package com.demo.webmagic.pageProcessor;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.http.HttpHost;

import com.demo.common.constant.ConstantDtoFlight;
import com.demo.common.model.Flightinfo;
import com.demo.common.model.Flighttrends;
import com.demo.common.model.Proxyip;
import com.demo.common.model._MappingKit;
import com.demo.common.tool.ToolOCR;
import com.demo.webmagic.dto.DtoFlightInfo;
import com.demo.webmagic.pipeline.PipelineVeryZhunFlightInfo;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.log.Log;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.druid.DruidPlugin;

import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Selectable;

public class PageProcessorHanglvzongheng implements PageProcessor {

	private static final Log log = Log.getLog(PageProcessorHanglvzongheng.class);
	
	private Site site = Site.me().setRetryTimes(3).setSleepTime(1000).setTimeOut(10000).setCycleRetryTimes(3).setCharset("utf-8");
	
	private DtoFlightInfo dtoFlightInfo = new DtoFlightInfo();
	
	private static final String pic_url_model = "http://www.umetrip.com/mskyweb/graphic.do?str=@picKey@&width=60&height=25&front=68,68,68&back=248,248,248&size=20&xpos=0&ypos=20";
	
	public PageProcessorHanglvzongheng() {
	}
	
	public PageProcessorHanglvzongheng(Proxyip proxyip) {
		HttpHost httpProxy = new HttpHost(proxyip.getIpStr(), Integer.parseInt(proxyip.getPortStr()));
		site.setHttpProxy(httpProxy);
	}
	public PageProcessorHanglvzongheng(List<Proxyip> proxyIpList) {
		List<String[]> httpProxyList = new ArrayList<String[]>();
		if(proxyIpList!=null && proxyIpList.size() > 0) {
			for (Proxyip proxyip : proxyIpList) {
				String[] httpProxy = new String[2];
				httpProxy[0] = proxyip.getIpStr();
				httpProxy[1] = proxyip.getPortStr();
				httpProxyList.add(httpProxy);
			}
			site.setHttpProxyPool(httpProxyList);
		}
	}
	
	@Override
	public Site getSite() {
		return site;
	}
	
	@Override
	public void process(Page page) {
		try {
			//System.out.println(page.getHtml());
			Selectable flightDetail = page.getHtml().xpath("//div[@class='del_com']");
			String fnoIsNotFound = flightDetail.xpath("//div[@class='err']").get();
			if(StrKit.isBlank(fnoIsNotFound) || "null".equals(fnoIsNotFound)) {
				Flightinfo flightinfo = new Flightinfo();
				String[] companyAndFno = flightDetail.xpath("//div[@class='tit']/span/b/text()").get().split(" ");
				if(companyAndFno!=null && companyAndFno.length == 2) {
					flightinfo.setCompany(companyAndFno[0]);
					flightinfo.setFno(companyAndFno[1]);
					dtoFlightInfo.setFno(companyAndFno[1]);
					flightinfo.setUpdateTime(new Date());
					
					List<Flighttrends> trendsList = new ArrayList<Flighttrends>();
					List<Selectable> stateList = flightDetail.xpath("//div[@class='reg']/text()").nodes();
					for (Selectable state : stateList) {
						Flighttrends flighttrends = new Flighttrends();
						flighttrends.setFlightStatus(state.get());
						trendsList.add(flighttrends);
					}
					
					List<Selectable> pInfoUlList  = flightDetail.xpath("//div[@class='p_info']/ul").nodes();
					for (int i = 0; i < pInfoUlList.size(); i++) {
						Flighttrends flighttrends = trendsList.get(i);
						List<Selectable> pInfoLiList = pInfoUlList.get(i).xpath("//li").nodes();
						
						if(pInfoLiList==null || (pInfoLiList.size() != 5 && pInfoLiList.size() != 4))
							throw new RuntimeException("获取航班信息失败!");
						
						flighttrends.setMileage(pInfoLiList.get(pInfoLiList.size()-4).xpath("//span/text()").get());
						flighttrends.setFlyTime(pInfoLiList.get(pInfoLiList.size()-3).xpath("//span/text()").get());
						flightinfo.setFlightType(pInfoLiList.get(pInfoLiList.size()-2).xpath("//span/text()").get());
						String imgSrc = pInfoLiList.get(pInfoLiList.size()-1).xpath("//img/@src").get();
						if(StrKit.isBlank(imgSrc))
							throw new RuntimeException("历史准点率获取失败!");
						
						String picUrl = pic_url_model.replace("@picKey@", imgSrc.substring(imgSrc.indexOf("=")+1, imgSrc.indexOf("&")));
						flighttrends.setZdl(ToolOCR.recognizeText(picUrl));
					}
					
					List<Selectable> flyBoxList  = flightDetail.xpath("//div[@class='fly_box']").nodes();
					for (int i = 0; i < trendsList.size(); i++) {
						Flighttrends flighttrends = trendsList.get(i);
						Selectable fromFlyBox = flyBoxList.get(i);
						Selectable toFlyBox = flyBoxList.get(i+1);
						flighttrends.setFromCity(fromFlyBox.xpath("//div[@class='f_tit']/h2/text()").get());
						flighttrends.setToCity(toFlyBox.xpath("//div[@class='f_tit']/h2/text()").get());
						
						Selectable fromTime;
						String jhqfImgSrc = "";
						String sjqfImgSrc = "";
						String jhjlImgSrc = "";
						String sjjlImgSrc = "";
						List<Selectable> fromTimeList = fromFlyBox.xpath("//div[@class='time']").nodes();
						if(fromTimeList.size() == 2) {
							fromTime = fromTimeList.get(1);
							
						} else {
							fromTime = fromTimeList.get(0);
						}
						List<Selectable> fromTimeDlList = fromTime.xpath("//dl").nodes();
						jhqfImgSrc = fromTimeDlList.get(0).xpath("//dt/img/@src").get();
						sjqfImgSrc = fromTimeDlList.get(1).xpath("//dt/img/@src").get();
						
						List<Selectable> toTimeList =toFlyBox.xpath("//div[@class='time']/dl").nodes();
						jhjlImgSrc = toTimeList.get(0).xpath("//dt/img/@src").get();
						sjjlImgSrc = toTimeList.get(1).xpath("//dt/img/@src").get();
						
						String jhqfImgUrl = pic_url_model.replace("@picKey@", jhqfImgSrc.substring(jhqfImgSrc.indexOf("=")+1, jhqfImgSrc.indexOf("&")));
						String sjqfImgUrl = pic_url_model.replace("@picKey@", sjqfImgSrc.substring(sjqfImgSrc.indexOf("=")+1, sjqfImgSrc.indexOf("&")));
						String jhjlImgUrl = pic_url_model.replace("@picKey@", jhjlImgSrc.substring(jhjlImgSrc.indexOf("=")+1, jhjlImgSrc.indexOf("&")));
						String sjjlImgUrl = pic_url_model.replace("@picKey@", sjjlImgSrc.substring(sjjlImgSrc.indexOf("=")+1, sjjlImgSrc.indexOf("&")));
						
						final Map<String, String> picUrlMap = new ConcurrentHashMap<String, String>();
						picUrlMap.put("jhqfImgUrl", jhqfImgUrl);
						picUrlMap.put("sjqfImgUrl", sjqfImgUrl);
						picUrlMap.put("jhjlImgUrl", jhjlImgUrl);
						picUrlMap.put("sjjlImgUrl", sjjlImgUrl);
						
						ExecutorService pool = Executors.newCachedThreadPool();  
						  
				        ArrayList<Callable<Integer>> callers = new ArrayList<Callable<Integer>>();
						
						for (final String key : picUrlMap.keySet()) {
							 callers.add(new Callable() {  
					                public Object call() throws Exception { 
					                	picUrlMap.put(key, ToolOCR.recognizeText(picUrlMap.get(key)));
					                    return null;  
					                }  
					            });
						}
						
						pool.invokeAll(callers);
						pool.shutdown();
						
						flighttrends.setJhqfTime(picUrlMap.get("jhqfImgUrl"));
						flighttrends.setSjqfTime(picUrlMap.get("sjqfImgUrl"));
						flighttrends.setJhddTime(picUrlMap.get("jhjlImgUrl"));
						flighttrends.setSjddTime(picUrlMap.get("sjjlImgUrl"));
						
						List<Selectable> fromFlyBoxFrPList = fromFlyBox.xpath("//div[@class='f_r']/p").nodes();
						flighttrends.setFromTemperature(fromFlyBoxFrPList.get(0).xpath("//p/text()").get());
						flighttrends.setFromWeather(fromFlyBoxFrPList.get(0).xpath("//b/text()").get());
						flighttrends.setFromNjd(fromFlyBoxFrPList.get(1).xpath("//p/text()").get().substring(5));
						flighttrends.setFromStatus(fromFlyBoxFrPList.get(2).xpath("//p/text()").get().substring(4));
						
						List<Selectable> toFlyBoxFrPList = toFlyBox.xpath("//div[@class='f_r']/p").nodes();
						flighttrends.setToTemperature(toFlyBoxFrPList.get(0).xpath("//p/text()").get());
						flighttrends.setToWeather(toFlyBoxFrPList.get(0).xpath("//b/text()").get());
						flighttrends.setToNjd(toFlyBoxFrPList.get(1).xpath("//p/text()").get().substring(5));
						flighttrends.setToStatus(toFlyBoxFrPList.get(2).xpath("//p/text()").get().substring(4));
						
						dtoFlightInfo.setCode(ConstantDtoFlight.code_success);
						dtoFlightInfo.setFlightInfo(flightinfo);
						dtoFlightInfo.setTrendsList(trendsList);
						dtoFlightInfo.setEnd(true);
					}
				} else {
					throw new RuntimeException("获取航班号失败!");
				}
			} else {
				dtoFlightInfo.setCode(ConstantDtoFlight.code_fno_invalid);
				dtoFlightInfo.setMessage(ConstantDtoFlight.message_fno_invalid);
				String url = page.getUrl().toString();
				dtoFlightInfo.setFno(url.substring(url.indexOf("=") + 1, url.indexOf("&")));
			}
		} catch(Exception e) {
			log.error(e.getMessage());
			log.error(page.getUrl().toString());
			dtoFlightInfo.setCode(ConstantDtoFlight.code_fail);
			dtoFlightInfo.setMessage(e.getMessage());
		} finally {
			page.putField("result", dtoFlightInfo);
		}
	}

	public DtoFlightInfo getDtoFlightInfo() {
		return dtoFlightInfo;
	}
	
	public static void main(String[] args) {
		
		PropKit.use("a_little_config.txt");
		DruidPlugin dp = new DruidPlugin(PropKit.get("jdbcUrl"), PropKit.get("user"), PropKit.get("password"));
		ActiveRecordPlugin arp = new ActiveRecordPlugin(dp);
		_MappingKit.mapping(arp);
		
		dp.start();
		arp.start();
		
		//Spider.create(new PageProcessorQunaer()).addUrl("http://flight.qunar.com/status/fquery.jsp?flightCode=CZ3974A").start();
		Spider.create(new PageProcessorHanglvzongheng()).addUrl("http://www.umetrip.com/mskyweb/fs/fc.do?flightNo=3U8669&date=2016-01-16&channel=").addPipeline(new PipelineVeryZhunFlightInfo()).start();
	}
}
